package com.example.p2pinvest.common;

import android.os.Build;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.example.p2pinvest.util.UIUtils;

/**
 * @author h2tc01
 * @version 1.0.0
 * 2022/8/3
 * 程序中的未捕获的全局异常的捕获(单例)
 *
 * 1.当出现未捕获异常时,能够给用户友好提示
 * 2.在出现异常时,能够将异常信息发送给后台
 */
public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private static CrashHandler crashHandler = null;

    private CrashHandler() {

    }

    public static CrashHandler getInstance() {
        if (crashHandler == null) {
            return new CrashHandler();
        }
        return crashHandler;
    }

    //系统默认的处理未捕获异常的处理器
    private Thread.UncaughtExceptionHandler handler;

    public void init() {
        handler = Thread.getDefaultUncaughtExceptionHandler();
        //将当前类设置为出现未捕获异常时的异常处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    //一旦系统出现未捕获的异常,就会调用这个方法
    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        //Log.e("TAG", "出现未捕获异常: " + e.getMessage());
        new Thread(() -> {
            //prepare() 和 loop() 中间的操作是在主线程中执行的
            //在android中,默认情况下一个线程是不可以调用Looper进行消息处理的,除非是主线程
            Looper.prepare();
            Toast.makeText(UIUtils.getContext(), "出现未捕获异常", Toast.LENGTH_SHORT).show();
            Looper.loop();
        }).start();

        //收集异常信息
        collectException(e);

        try {
            Thread.sleep(2000);
            //移除当前activity
            ActivityManager.getInstance().removeCurrent();
            //结束当前的进程
            android.os.Process.killProcess(android.os.Process.myPid());
            //结束虚拟机
            System.exit(0);
        } catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();
        }
    }

    private void collectException(Throwable e){
        String message = e.getMessage();
        //收集具体的客户的手机,系统的信息
        String info = Build.DEVICE + ":" + Build.MODEL + ":" + Build.PRODUCT + ":" + Build.VERSION.SDK_INT;
        //发送异常信息给后台
        new Thread(() -> {
            //需要按照指定的url访问后台的服务,将异常信息发送过去
            Log.e("TAG", "collectException: " + message);
            Log.e("TAG", "collectException: " + info);
        }).start();
    }
}
